首先介绍 NSThread 创建线程的方法:
  | 
  | 
public class NSThread : NSObject  从这里可以看出,NSThread 是继承自 NSObject 的类,它的创建是一个构造器 init  ,所以使用实例化对象的方式就可以调用了。
  | 
  | 
现在我们来看一下,这个方法的几个参数,分别代表的含义。
| 形参名 | 形参类型 | 作用 | 方法填写 | 
|---|---|---|---|
| target | AnyObject | 当前类的一个对象。是selector消息发送的对象。 | 一般是 self | 
| selector | Selector | 线程要执行的方法。只能接收一个参数。 | 创建方法传入 | 
| object | AnyObject? | selector线程函数的唯一传入值,可以是 nil 。 | nil | 
下面,我们要做的是通过点击,来调用 NSThread。
我们在ViewController里创建一个touchesBegan的方法,并创建一个对象接收线程:
  | 
  | 
然后我们在ViewController 中创建 run 这个方法:
  | 
  | 
在 touchesBegan 方法中,启动线程:
  | 
  | 
现在我们运行模拟器,点击一下屏幕,控制台打印出:
  | 
  | 
number = 2, name = (null) 所以我们成功使用了NSThread 子线程。
我是run的传入值,表示 init 构造器的第三个参数,同时也是第二个参数的传入值。
isMainThread mainThread
这三个的表达式如下
  | 
  | 
我们来看一下这三个表达式的含义
| 名字 | 类型 | 作用 | 
|---|---|---|
| var isMainThread | 计算属性,返回 bool 类型。 | 判断一条线程是不是主线程 | 
| func isMainThread | 类型方法,返回 bool 类型。 | 判断一条线程是不是主线程 | 
| func mainThread | 类型方法, 返回线程类型。 | 返回当前线程里的主线程 | 
现在我们来使用 var isMainThread 计算属性做一个判断,我们在 TouchesBengan 方法中写入:
  | 
  | 
在 run 方法中写入:
  | 
  | 
运行程序,点击屏幕,控制台输出:
  | 
  | 
通过  isMainThread 我们可以得知当前方法所在的线程。
接下来,我们通过 mainThread 来获取主线程,首先我们在 run 这个方法中写入 :
  | 
  | 
运行程序,点击屏幕,控制台输出:
  | 
  | 
我们在子线程中获得了主线程,可以说明, func mainThread 返回的是一个主线程。
栈大小 stackSize
下面是它的表达式:
  | 
  | 
由此可以看出,stackSize 是一个储存属性的整型。
每个线程在创建时都会分配一块内存空间,这个内存空间叫做自有栈,下面我们来看下,一个线程的栈是多少,我们在 TouchesBengan 方法中写入:
  | 
  | 
因为 stackSize 传回的是字节数,所以我们 /1024 是它转为 KB,打印结果如下:
  | 
  | 
由此可以看出,主线程和子线程的栈大小均为 512KB。值得注意的是,stackSize 并不是一个只读属性,可以进行赋值,我们在 TouchesBengan 中写入:
  | 
  | 
打印结果为:
  | 
  | 
这个结果相当灵异,栈的大小是否真的有了变化,还需要进一步考证。
线程的优先级
表达式如下:
  | 
  | 
先来看下默认的优先级:
  | 
  | 
打印结果为:
  | 
  | 
优先级是CUP处理线程时的权重,同等条件下,优先级越高的线程,优先获得CUP的处理时间。为了验证这一点,我们再创建一个线程。在 TouchesBengan 方法中,写入以下代码:
  | 
  | 
现在我们有了两条线程,两个线程共同执行 run 这个方法,在这个方法中我们使用 for 循环输出一句话:
  | 
  | 
运行,控制台输出如下:
  | 
  | 
可以看出,在优先级相同的情况下,两个线程轮流执行。现在我们修改线程的优先级:
  | 
  | 
输出结果为:
  | 
  | 
可以看到,刚开始运行时,基本都是权重高的进程在计算,需要注意的是,优先级要设定在另一个进程 start 之前,写在 start 之后无效。
其他属性和方法
  | 
  |